#include "queue.h"
#include <QtGui>

Queue::Queue(QObject *parent) :
    QObject(parent)
{
    timeOutTimer = new QTimer(this);
    timeOutTimer->setInterval(DEFAULT_TIMEOUT_TIME);

    connect(timeOutTimer, SIGNAL(timeout()), this, SLOT(noOKanswer()));

    reset();
}

void Queue::addCommand(const Returnables::RequestId &command, QList<QVariant> param)
{
    if (state == Queue::FREEZE)
    {
        qDebug() << "Queue::addCommand() -- State FREEZE";
    }
    else if(commandsQueue.length() == DEFAULT_QUEUE_MAX)
    {
        qDebug() << "Queue::addCommand -- commandsQueue.length() == DEFAULT_QUEUE_MAX ";
        state = Queue::FREEZE;
        emit stateChanged(state);
    }
    else
    {
        qDebug() << "Queue::addCommand() -- APPEND TO LIST";
        commandsQueue.append(command);
        paramQueue.append(param);
        if(state == Queue::NOT_RUNNING){ getCommand(); }
    }
}

void Queue::getCommand()
{
    qDebug() << "Queue::getCommand() -- change state to RUN::WAIT_ANSWER";
        timeOutTimer->start();
        state = Queue::WAIT_ANSWER;
        emit stateChanged(state);
        currentCommand = commandsQueue.takeFirst();
        currentParam = paramQueue.takeFirst();
        emit returnCommand(currentCommand, currentParam);
}

void Queue::noOKanswer()
{
    state = Queue::FREEZE;
    emit stateChanged(state);
    if(errorCounter++ != 3)
    {
        qDebug() << "Queue::noOKanswer()";
        emit lostAnswer();
        emit returnCommand(currentCommand, currentParam);
    } else {
        qDebug() << "Queue::noOKanswer() -- networkError";
        emit networkError();
        OKanswer();
    }
}

void Queue::OKanswer()
{
    errorCounter = 0;
    if(state == Queue::WAIT_ANSWER || state == Queue::FREEZE)
    {
        if(!commandsQueue.isEmpty())
        {
            qDebug() << "Queue::OKanswer() -- Get next command";
            getCommand();
        } else {
            state = Queue::NOT_RUNNING;
            emit stateChanged(state);
            timeOutTimer->stop();
            qDebug() << "Queue::OKanswer() -- change state to NOT_RUNNING, TIMER STOPPED";
        }
    }
}

void Queue::reset()
{
    timeOutTimer->stop();
    commandsQueue.clear();
    paramQueue.clear();
    errorCounter = 0;
    state = Queue::NOT_RUNNING;
}

Queue::~Queue()
{

}
